/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 言初
 * Date: 2023-12-25
 * Time: 22:15
 */

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
import java.util.*;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 言初
 * Date: 2023-10-10
 * Time: 20:41
 */


//如何对于这个数组进行关于x（列）坐标的排序呢？（排序已经弄好了）
// 首先如何表示一个坐标位置(x,y) 使用一个point类，和其中的相关方法来进行实现。
class point {
    private double x;
    private double y;

    public point(double x,double y){
        this.x=x;
        this.y=y;
    }

    public double getX() {
        return x;
    }
    public double getY(){
        return y;
    }

}

public class Main7 {
    // 7-7 平面最近点对（分治版）
    // 最终的答案就会是三种情况：
    //1.都在左侧数组中
    //2.都在右侧数组中
    //3.一个在左侧数组中，一个在右侧数组中

    //思路：
    //先给数组排序，按照x（列）来进行排序
    //分治思想，依次遍历这个数组的左右子数组，然后找到左右子数组中的最近点对的距离 mleft 和 mright
    //然后，比较mleft和mright的大小，把较小值赋给d

    //以d为标准，在数组的mid值附近找到 x值的区间在 【[mid-d,mid+d]内的所有的点
    //把找到的这些点按照y（行）来进行排序，找到 [y,y+d] 范围内的所有点依次和这个y值的点进行求解dmid的值，然后让dmid的值和d的值进行比较
    //让d等于较小值
    //先以x坐标来进行一下排序，后续会对y坐标来进行一下排序


    public static double d=Double.MAX_VALUE ; // 值初始化为double类型的最大值。
    //使用d来存储最小点对的距离值

    public static void func(List<point> points,int left, int right){
        if(left>=right){
            return ;
        }
        //点对的距离值，至少也得有2个点。
        //当有三个点的时候就可以 比较 求解 赋值 返回 了
        if(right-left+1==2){

            //计算这2点之间的距离，然后和d进行比较，
            double dd=func1(points.get(left),points.get(right));
            if(dd<d){
                d=dd;
            }
            //比较之后，返回
            return;
        }

        if(right-left+1==3){

            //对这3个点进行依次求解距离值，然后找到一个最小的值和d进行比较
            // left,left+1,right
            // left和left+1
            // left和right
            //left+1和right
            double dd1=func1(points.get(left),points.get(left+1));
            double dd2=func1(points.get(left),points.get(right));
            double dd3=func1(points.get(left+1),points.get(right));

            double dd=(dd1>dd2)?dd2:dd1;
            double ddd=(dd>dd3)?dd3:dd;
            //把较小值赋给dd和ddd
            if(ddd<d){
                d=ddd;
            }
            //比较之后返回
            return;
        }

        //点的个数大于3的情况
        int mid=(right+left)/2;
        func(points,left,mid);
        func(points,mid+1,right);


        //左右子数组都走过之后，此次的d的值就是2个点都在左边的子数组 和 2个点都在右边的子数组中的 最小的点对的距离了
        //走到这里，此后我们需要做的就是：
        //以d为边长在 x（列）==mid 的两边 搞了一个2d的距离范围 就是找到所有x的范围在[mid-d,mid+d] 之间的点放到一个新的链表中
        List<point> list=new ArrayList<>();
        for(int i=left;i<=right;i++){
            if(i>=mid-d && i<=mid+d){
                list.add(points.get(i));
            }
        }
        //然后把这些点针对y（行）来进行了排序， 排好序以后，遍历到每一个点的时候，要求 所需要计算的点对要求y值之差是要小于等于d的
        Collections.sort(list,new Comparator() {

            @Override
            public int compare(Object o1, Object o2) {
                point p1 = (point) o1;
                point p2 = (point) o2;

                //这个写法是针对y（行）坐标来进行排序的
                return Double.compare(p1.getY(), p2.getY());
            }

        });
        // 排好序以后，遍历到每一个点的时候，它的y（行）已知，然后需要和它进行点对距离计算 的要求就是：[y-d,y+d] 要求：y1-y<=d
        int len=list.size();
        for(int i=0;i<len;i++){
            point ret1=list.get(i);
            double y=ret1.getY();

            for(int j=i+1;j<len;j++){
                point ret2=list.get(j);
                double y2=ret2.getY();
                if(Math.abs(y2-y)<=d){
                    double dd=func1(ret1,ret2);
                    if(dd<d){
                        d=dd;
                    }
                }else{
                    break;
                }
            }

        }
    }


    // 求2点距离的方法
    public static double func1(point p1,point p2){
        double x1=p1.getX();
        double y1=p1.getY();

        double x2=p2.getX();
        double y2=p2.getY();

        double dis=Math.pow((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2),0.5);
        return dis;
    }



    public static void main(String[] args) throws IOException {
        List<point> points = new ArrayList<>();


        StreamTokenizer st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
        st.nextToken();
        int n = (int) st.nval;

        for (int i = 0; i < n; i++) {
            st.nextToken();
            double x = (double) st.nval;
            st.nextToken();
            double y = (double) st.nval;
            points.add(new point(x,y));
        }




        Collections.sort(points,new Comparator() {

            @Override
            public int compare(Object o1, Object o2) {
                point p1 = (point) o1;
                point p2 = (point) o2;

                //这个写法是针对x（列）坐标来进行排序的
                return Double.compare(p1.getX(), p2.getX());
            }

        });



        //大于等于三个点的时候才需要调用func方法。
        func(points,0,points.size()-1);

        System.out.printf("%.4f",d);
    }
}

